# This is a sample Python script.

# Press Shift+F10 to execute it or replace it with your code.
# Press Double Shift to search everywhere for classes, files, tool windows, actions, and settings.

import csv
import statistics
import matplotlib.ticker as ticker
from pylab import *


# 根据"data_log.csv"中记录的回测期间的持仓及收益信息计算最大回撤及夏普比率
# 将持仓市值及每个交易日相对于表中上一个交易日的收益率（表中第一个交易日的收益率基于初始持仓市值计算）、以及最大回撤和夏普比率可视化
# 最大回撤基于持仓市值计算，夏普比率基于每个交易日相对于表中上一个交易日的收益率计算（表中第一个交易日的收益率基于初始持仓市值计算）

class Visualization:  # 将回测期间的市值、各交易日收益率、夏普比率和最大回撤绘制成图
    def buildlist(self, start_date, end_date):  # 生成回测期间表中各交易日日期、市值、收益率（基于表中上一个交易日，若为第一个交易日则基于初始市值）的列表
        with open("./data_log.csv", "r") as inFile:
            csvReader = csv.reader(inFile)
            date_list = []
            value_list = []
            rate_list = []
            for line in csvReader:
                date_list.append(line[0])
                value_list.append(line[1])
            idx1 = date_list.index(start_date)
            idx2 = date_list.index(end_date)
            del value_list[0]
            value_list = ['10000'] + value_list
            for i in range(len(value_list)):
                if i == 0:
                    rate_list.append(0)
                else:
                    rate_list.append((float(value_list[i])-float(value_list[i-1]))/float(value_list[i-1]))
            date_list = date_list[idx1:(idx2 + 1)]
            value_list = value_list[idx1:(idx2 + 1)]
            rate_list = rate_list[idx1:(idx2+1)]
            build_list = [date_list, value_list, rate_list]
        return build_list

    def maxdrawdown(self, start_date, end_date):  # 计算最大回撤
        data_list = self.buildlist(start_date, end_date)[1]
        data_list2 = []
        for ch in data_list:
            data_list2.append(float(ch))
        drawdownlist = []
        for i in range(len(data_list2) - 1):
            drawdown = (data_list2[i] - min(data_list2[(i + 1):])) / data_list2[i]
            if drawdown > 0:
                drawdownlist.append(drawdown)
            else:
                drawdown = 0
                drawdownlist.append(drawdown)
        maxdrawdown = max(drawdownlist)
        return maxdrawdown

    def sharperatio(self, start_date, end_date, rf):  # 计算夏普比率，其中rf为日无风险收益率
        data_list = self.buildlist(start_date, end_date)[2]
        Mean = statistics.mean(data_list)
        Std = statistics.stdev(data_list)
        sharpe_ratio = (Mean - rf) / Std
        return sharpe_ratio

    def visualization(self, start_date, end_date, rf):  # 进行可视化，输入回测开始时间、结束时间和回测期间的日无风险收益率（rf)
        date_list = self.buildlist(start_date, end_date)[0]
        value_list1 = self.buildlist(start_date, end_date)[1]
        value_list = []
        for ch in value_list1:
            value_list.append(float(ch))
        rate_list = self.buildlist(start_date, end_date)[2]
        md = self.maxdrawdown(start_date, end_date)
        sr = self.sharperatio(start_date, end_date, rf)
        plt.figure(1)
        plt.subplot(311)
        mpl.rcParams['font.sans-serif'] = ['SimHei']
        matplotlib.rcParams['axes.unicode_minus'] = False
        plt.plot(date_list, value_list)
        title1 = '持仓总市值' + '   ' + '（最大回撤：' + str(round(md*100, 2)) + '%）'
        plt.title(title1)
        plt.gca().xaxis.set_major_locator(ticker.MultipleLocator(100))
        plt.subplot(313)
        mpl.rcParams['font.sans-serif'] = ['SimHei']
        matplotlib.rcParams['axes.unicode_minus'] = False
        plt.plot(date_list, rate_list)
        title2 = '基于上一交易日的收益率' + '   ' + '（夏普比率：' + str(round(sr*100, 2)) + '%）'
        plt.title(title2)
        plt.gca().xaxis.set_major_locator(ticker.MultipleLocator(100))
        plt.show()


visual_ = Visualization()
visual_.visualization('2015-01-06', '2019-12-27', 0.000111)










